package utils;

import java.awt.geom.Line2D;
import java.awt.geom.Point2D;


public abstract class MathUtils {
	/**
	 * Trims STEAL inputs and ensures they conform to small and large numbers.
	 * @param value the number to trim
	 * @return
	 */
	public static float capValue(float value) {
		if (Math.abs(value) <= -Math.pow(10, 7)) {
			return (float)(-Math.pow(10, 7) + 1.0);
		}
		else if (Math.abs(value) < Math.pow(10, -3)) {
			return 0.0f;
		}
		else if (value >= Math.pow(10, 7)) {
			return  (float) (Math.pow(10, 7) - 1.0);
		}
		else {
			return value;
		}
	}
	
	/**
	 * Calculates the dot product of two lines
	 * @param line1 The first line.
	 * @param line2 The second line.
	 * @return The dot product of two lines.
	 */
	public static double dotProduct(Line2D line1, Line2D line2){
		
		Point2D line1Start = line1.getP1();
		Point2D line1End = line1.getP2();
		
		Point2D line1Vector = new Point2D.Double(line1End.getX() - line1Start.getX(),line1End.getY() - line1Start.getY());
		double line1Mag = line1Start.distance(line1End);
		
		Point2D line2Start = line2.getP1();
		Point2D line2End = line2.getP2();
		
		Point2D line2Vector = new Point2D.Double(line2End.getX() - line2Start.getX(),line2End.getY() - line2Start.getY());
		double line2Mag = line2Start.distance(line2End);
		
		return Math.acos((line1Vector.getX()*line2Vector.getX() + line1Vector.getY()*line2Vector.getY())/(line1Mag*line2Mag));
		
	}

	/**
	 * Calculates the dot product of two points.
	 * @param point1 The first point.
	 * @param point2 The second point.
	 * @return The dot product of two points.
	 */
	public static double dotProduct(Point2D point1, Point2D point2){
		Line2D line1 = new Line2D.Double(0, 0, point1.getX(), point1.getY());
		Line2D line2 = new Line2D.Double(0, 0, point2.getX(), point2.getY());
		return dotProduct(line1, line2);
	}

	public static Point2D[] getTangentPoints(Point2D point1,
			Point2D point2, double radius) {
		Point2D[] tangentPoints = new Point2D[2];
		if (point2.getX() < 166  && point2.getX() > 164 && point2.getY() > 160 && point2.getY() < 161) {
			System.out.println("test");
		}
		Vector2D vectorBetweenPoints = new Vector2D(point2.getX()-point1.getX(),
				point2.getY()-point1.getY());
		Vector2D orthVec = vectorBetweenPoints.getOrthogonalUnitVector();
		orthVec.scale(radius);
		tangentPoints[0] = new Point2D.Double(
				point2.getX() + orthVec.x, point2.getY() + orthVec.y);
		tangentPoints[1] = new Point2D.Double(
				point2.getX() - orthVec.x, point2.getY() - orthVec.y);
		return tangentPoints;
	}
	
	/*public static Line2D[] findTangentLines(Point2D playerPosition, ViewObstacle blocker, double angle, double viewAngle){
		double radius = blocker.getRadius();
		double distance = playerPosition.distance(blocker.getPosition());
		double beta = (float)Math.toDegrees(Math.asin(radius/distance));
		double tangentAngle1 = angle+beta;
		double tangentAngle2 = angle-beta;
		if (Math.abs(tangentAngle1-viewAngle) > 60) {
			return null;
		}
		Line2D[] returnArray = new Line2D.Double[2];
		returnArray[0] = new Line2D.Double(playerPosition.getX(),
				playerPosition.getY(),
				playerPosition.getX() + Math.cos(tangentAngle1)*distance,
				playerPosition.getY() + Math.sin(tangentAngle1)*distance);
		returnArray[1] = new Line2D.Double(playerPosition.getX(),
				playerPosition.getY(),
				playerPosition.getX() + Math.cos(tangentAngle2)*distance,
				playerPosition.getY() + Math.sin(tangentAngle2)*distance);
		return returnArray;
		
	}

	public static boolean inViewRadius(Point2D position, Point2D position2) {
		if (position.distance(position2) < GameConstants.PLAYER_VIEW_DIST) {
			return true;
		} else {
			return false;
		}
	}
	
	public static Line2D.Double checkVisionLimit(double angle, Point2D player1, Point2D player2){
		double angle1 = angle+60;
		if(angle1 >=360){
			angle1 -=360;
		}
		double angle2=angle-60;
		if(angle2 <=0 ){
			angle2 += 360;
		}
		Point2D.Double end1 = new Point2D.Double(
				player1.getX()+Math.cos(Math.toRadians(angle1))*GameConstants.PLAYER_VIEW_DIST,
				player1.getY()+Math.sin(Math.toRadians(angle1))*GameConstants.PLAYER_VIEW_DIST);
		Point2D.Double end2 = new Point2D.Double(
				player1.getX()+Math.cos(Math.toRadians(angle2))*GameConstants.PLAYER_VIEW_DIST,
				player1.getY()+Math.sin(Math.toRadians(angle2))*GameConstants.PLAYER_VIEW_DIST);
		Line2D.Double line1 =new Line2D.Double(player1, end1);
		Line2D.Double line2 =new Line2D.Double(player1, end2);
		
		if(line1.ptSegDist(player2)<GameConstants.PLAYER_RADIUS){
			return line1;
		}
		else if(line2.ptSegDist(player2)<GameConstants.PLAYER_RADIUS){
			return line2;
		}
			return null;
		
		
	}
	*/
}
